package com.test;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.TreeMap;

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.codec.Constant;
import com.codec.MessageCodecFactory;
import com.codec.MessagePack;

/**
 * 503获取成员
 * @author linjinquan
 */
public class XdRoom517 extends AbstractJavaSamplerClient {
	
	static Logger logger = LoggerFactory.getLogger(XdRoom517.class);

	/**
	 * Jmeter控制台输入的参数.
	 */
	private String ip = Constant.IP_ADDR;
	private int port = Constant.IP_PORT;

	static Map<String, String> paramMap = new TreeMap<>();
	static {
		paramMap.put("agreeId", "7");
		paramMap.put("type", "517");
		paramMap.put("loginUserId", "80000124");
		paramMap.put("jmt_token", Constant.JMT_TOKEN);
		
		paramMap.put("roomId", "80000124");
		paramMap.put("sex", "1");//515
		paramMap.put("message", "517预匹配");
		
	}

	/**
	 * 初始化方法，实际运行时每个线程仅执行一次，在测试方法运行前执行，<br>
	 * 类似于LoadRunner中的init方法. {@inheritDoc}
	 * 
	 * @see org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient#setupTest(
	 *      org.apache.jmeter.protocol.java.sampler.JavaSamplerContext)
	 * @author ices 2013-3-18 上午8:44:51 <br>
	 */
	@Override
	public void setupTest(JavaSamplerContext arg0) {
		ip = arg0.getParameter("ip", ip);
		port = arg0.getIntParameter("port", port);
		for (Map.Entry<String, String> entry : paramMap.entrySet()) {
			paramMap.put(entry.getKey(), arg0.getParameter(entry.getKey()));
		}

	}

	/**
	 * 设置传入的参数，可以设置多个，已设置的参数会显示到Jmeter的参数列表中. {@inheritDoc}
	 * 
	 * @see org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient
	 *      #getDefaultParameters()
	 * @author ices 2013-3-18 上午8:45:02 <br>
	 */
	@Override
	public Arguments getDefaultParameters() {
		Arguments params = new Arguments();
		/*
		 * 定义一个参数，显示到Jmeter的参数列表中， 第一个参数为参数默认的显示名称， 第二个参数为默认值
		 */
		params.addArgument("ip", ip);
		params.addArgument("port", port + "");
		for (Map.Entry<String, String> entry : paramMap.entrySet()) {
			params.addArgument(entry.getKey(), entry.getValue());
		}
		return params;
	}

	/**
	 * 测试执行的循环体，根据线程数和循环次数的不同可执行多次，类似于LoadRunner中的Action方法 {@inheritDoc}
	 * 
	 * @see org.apache.jmeter.protocol.java.sampler.JavaSamplerClient#runTest(
	 *      org.apache.jmeter.protocol.java.sampler.JavaSamplerContext)
	 * @author ices 2013-3-18 上午8:45:18 <br>
	 */
	@Override
	public SampleResult runTest(JavaSamplerContext arg0) {

		SampleResult results = new SampleResult();
		try {
			results.sampleStart();
			IoConnector connector = new NioSocketConnector();
			connector.getSessionConfig().setReadBufferSize(1024 * 1024 * 10);
			connector.getFilterChain().addLast("logger", new LoggingFilter());
			connector.getFilterChain().addLast("codec",
					new ProtocolCodecFilter(new MessageCodecFactory(Charset.forName("utf-8")))); // cs要一致
			connector.setHandler(new MinaClientHandler(results));
			ConnectFuture future = connector.connect(new InetSocketAddress(ip, port));

			future.awaitUninterruptibly();

			IoSession session = future.getSession();
			session.getConfig().setUseReadOperation(true);
			session.getCloseFuture().awaitUninterruptibly();
			connector.dispose();

		} catch (Exception e) {
			results.setSuccessful(false);
		}
		return results;
	}

	/**
	 * 结束方法，实际运行时每个线程仅执行一次，在测试方法运行结束后执行，<br>
	 * 类似于LoadRunner中的end方法. {@inheritDoc}
	 * 
	 * @see org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient#teardownTest(
	 *      org.apache.jmeter.protocol.java.sampler.JavaSamplerContext)
	 * @author ices 2013-3-18 上午8:45:53 <br>
	 */
	@Override
	public void teardownTest(JavaSamplerContext arg0) {
	}

	/** 内部类，调用方法 **/
	private static class MinaClientHandler extends IoHandlerAdapter {
		private SampleResult results;

		public MinaClientHandler(SampleResult results) {
			this.results = results;
		}

		@Override
		public void sessionOpened(IoSession session) {
			MessagePack pack = null;
			JSONObject jsonObject = new JSONObject();
			for (Map.Entry<String, String> entry : paramMap.entrySet()) {
				try {
					jsonObject.put(entry.getKey(), entry.getValue());
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}
			int type = Integer.valueOf(paramMap.get("type"));
			pack = new MessagePack(type, type, jsonObject.toString());
			session.write(pack);
			results.setSuccessful(true);
		}

		@Override
		public void messageReceived(IoSession session, Object message) {
			MessagePack messagePack = (MessagePack) message;
			logger.debug("客户端接收：type={},content={}",messagePack.getType(), messagePack.getContent());
			results.setResponseData(messagePack.getContent(), null);// 第二个参数指定编码方法
			results.sampleEnd();
			session.close(true);
		}

		@Override
		public void exceptionCaught(IoSession session, Throwable cause) {
			session.close(true);
		}
	}
}